//   const  PUBLISH = 'PUBLISH'
//     const   SUBSCRIBE = 'SUBSCRIBE'
//     const  UNSUBSCRIBE = 'UNSUBSCRIBE'

// class MQEvent {
//     head:MQHead;
//     body:any;
// }

// class MQHead {
//     topic:string;
//      type:string
//     id:string;
// }

/**
 * 基于websocket的消息订阅/发布客户端
 */
export default {
  uri: null,
  ws: null,
  //断线重联间隔时间
  reconnectInterval: 1000,
  subscribes: {},
  callBackList: [],
  connect(fun) {
    if (this.ws) {
      if (this.ws.readyState == WebSocket.OPEN) {
        fun();
      } else {
        this.callBackList.push(fun);
      }
    } else {
      this.callBackList.push(fun);
      this.createConnect();
    }
  },
  createConnect() {
    this.ws = new WebSocket(this.uri);

    this.ws.onmessage = (message) => {
      console.debug("on message", message);
      let event = JSON.parse(message.data);
      let subscribe = this.subscribes[event.head.topic];
      if (subscribe) {
        subscribe.callBack(event);
      } else {
        console.warn("消息处理器丢失", event);
      }
    };

    this.ws.onopen = () => {
      const arr = this.callBackList;
      this.callBackList = [];
      arr.forEach((e) => e());
    };
    this.ws.onerror = (error) => console.error("连接出错了:", error);
    this.ws.onclose = () =>
      setTimeout(this.createConnect(), this.reconnectInterval);
  },
  /**
   * 订阅
   * @param {String} topic 主题
   * @param {String} id 用于取消订阅的id
   * @param {fun} callBack 回调
   */
  subscribe(topic, id, callBack) {
    console.debug(`subscribe topic:${topic} id:${id}`);
    this.subscribes[topic] = { id, callBack };

    this.connect(() => {
      this.sendObj({
        head: {
          topic,
          type: "SUBSCRIBE",
          id,
        },
      });
    });
  },

  /**
   * 取消订阅
   * @param {String} topic 主题,目前对于取消订阅没有实际作用,只是用于标记
   * @param {String} id 订阅时指定的id
   */
  unsubscribe(topic, id) {
    console.debug(`unsubscribe topic:${topic} id:${id}`);
    delete this.subscribes[topic];

    this.connect(() => {
      this.sendObj({
        head: {
          topic,
          type: "UNSUBSCRIBE",
          id,
        },
      });
    });
  },
  //发布
  publish(topic, data) {
    console.debug(`publish topic:${topic} data:`, data);

    this.connect(() => {
      this.sendObj({
        head: {
          topic,
          type: "PUBLISH",
        },
        body: data,
      });
    });
  },
  sendObj(obj) {
    this.ws.send(JSON.stringify(obj));
  },
};
